using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Kontakter
{
    public partial class PrivateForm : Form
    {
        private Logic logic;

        private int friendId;

        private List<Message> messages = new List<Message>();

        private Thread readFriendNewMessagesThread;

        private delegate void SetOutputMessages(List<Message> messages);

        public PrivateForm(Logic l, int id)
        {
            logic = l;
            friendId = id;

            InitializeComponent();
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            this.Text = logic.Friends[friendId].Name;

            messages = logic.GetMessagesHistory(friendId);
            WriteOutputMessages(messages);

            StartReadingFriendNewMessages(friendId);

            logic.FriendsUpdated += new Logic.FriendsUpdatedEventHandler(FriendsUpdated);

            privateIn.KeyDown += new KeyEventHandler(OnPrivateInKeyDown);
            privateIn.Focus();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            logic.FriendsUpdated -= new Logic.FriendsUpdatedEventHandler(FriendsUpdated);
        }

        private void FriendsUpdated(object sender, int friendId, UpdateType type)
        {
            if (friendId != -1 && friendId == this.friendId && type == UpdateType.NewMessagesCount)
            {
                StartReadingFriendNewMessages(friendId);
            }
        }

        private void StartReadingFriendNewMessages(int friendId)
        {
            readFriendNewMessagesThread = new Thread(new ParameterizedThreadStart(ReadFriendNewMessages));
            readFriendNewMessagesThread.Start(friendId);
        }

        private void ReadFriendNewMessages(object id)
        {
            int friendId = (int)id;

            List<Message> newMessages = logic.ReadFriendNewMessages(friendId);
            if (newMessages.Count != 0)
            {
                WriteOutputMessages(newMessages);
                logic.FastUpdate();
            }
        }

        private void WriteOutputMessages(List<Message> messages)
        {
            if (this.privateOut.InvokeRequired)
            {
                SetOutputMessages d = new SetOutputMessages(WriteOutputMessages);
                this.Invoke(d, new object[] { messages });
            }
            else
            {
                messages.Reverse();
                foreach (Message msg in messages)
                {
                    string body = msg.MessageBody;
                    body = Utils.RemoveStringFormatting(body);
                    body = Utils.RemovePrecedingSpaces(body);
                    body = Utils.RemoveSucceedingSpaces(body);
                    privateOut.AppendText(msg.Date + ", " + msg.Author + "\n" + body + "\n\n");
                }

                privateOut.ScrollToCaret();

                if (!this.ContainsFocus)
                    this.Activate();
            }
        }

        private void CloseForm()
        {
            this.Close();
        }

        private void OnPrivateInKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (privateIn.Text.Length == 0)
                    return;

                StringBuilder sb = new StringBuilder(privateIn.Text);
                if (sb[0] == '\n')
                    sb.Remove(0, 1);

                logic.SendMessage(friendId, sb.ToString());
                privateOut.AppendText("> " + sb.ToString() + "\n\n");
                privateOut.ScrollToCaret();

                privateIn.Clear();
            }
        }
    }
}
